package pl.edu.agh.sius.utils;

import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import pl.edu.agh.sius.controller.Concern1Controller;
import pl.edu.agh.sius.controller.Concern2Controller;
import pl.edu.agh.sius.controller.Concern3Controller;
import pl.edu.agh.sius.controller.ConcernController;
import pl.edu.agh.sius.controller.FirstChoiceBB.Concern;

public class FacesHelper {

	public static final String SOURCE_EMAIL = "SourceEmail";
	public static final String SOURCE_PASSWORD = "SourcePassword";
	public static final String SOURCE_HOST = "SourceHost";
	public static final String SOURCE_PORT = "SourcePort";
	public static final String DESTINATION = "Destination";
	
	public boolean getHasSomeMessages() {
		return FacesHelper.getHasMessages();
	}

	private static Logger log = Logger.getLogger(FacesHelper.class.getName());
	
	public static boolean getHasMessages() {
		return FacesContext.getCurrentInstance().getMessages().hasNext();
	}

	public static void activateController(Concern concern) throws Exception {
		String AC = "activeController";
		/*
		if (getBeanA(AC) != null) {
			getBeanB(AC, ConcernController.class).restart();
			return;
		}
		*/
		ConcernController cc;
		switch (concern) {
		case ESTATE_SPLIT: {
			cc = new Concern1Controller();
			break;
		}
		case TEMPORAL_BENEFIT: {
			cc = new Concern2Controller();
			break;
		}
		case WASTE_TRANSPORT: {
			cc = new Concern3Controller();
			break;
		}
		default:
			throw new Exception(
					"Nie udaĹ‚o siÄ™ utworzyÄ‡ wĹ‚aĹ›ciwiego kontrolera.");
		}
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put(AC, cc);
	}

	public static void addMessage(String message, FacesMessage.Severity severity) {
		if (severity == null) {
			severity = FacesMessage.SEVERITY_ERROR;
		}
		FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(severity, message, message));
	}

	public static Object getBeanA(String beanName) {
		FacesContext context = FacesContext.getCurrentInstance();
		return context.getELContext().getELResolver().getValue(
				context.getELContext(), null, beanName);
	}

	@SuppressWarnings("unchecked")
	public static <T> T getBeanB(String beanName, Class<T> c) {
		FacesContext context = FacesContext.getCurrentInstance();
		return (T) context.getApplication().getExpressionFactory()
				.createValueExpression(context.getELContext(),
						"#{" + beanName + "}", c).getValue(
						context.getELContext());
	}

	@SuppressWarnings("unchecked")
	public static <T> T getBeanC(String beanName, Class<T> c) {
		FacesContext context = FacesContext.getCurrentInstance();
		return (T) context.getApplication().evaluateExpressionGet(context,
				"#{" + beanName + "}", c);
	}

	public static String lookupManagedBeanName(Object bean) {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		Map<String, Object> requestMap = externalContext.getRequestMap();

		for (String key : requestMap.keySet()) {
			if (bean.equals(requestMap.get(key))) {
				return key;
			}
		}

		Map<String, Object> sessionMap = externalContext.getSessionMap();

		for (String key : sessionMap.keySet()) {
			if (bean.equals(sessionMap.get(key))) {
				return key;
			}
		}

		Map<String, Object> applicationMap = externalContext
				.getApplicationMap();

		for (String key : applicationMap.keySet()) {
			if (bean.equals(applicationMap.get(key))) {
				return key;
			}
		}

		return null;
	}
	
	public static String getFacesProperty(String key) {
		FacesContext fc = FacesContext.getCurrentInstance();
		String p = null;
		if (fc != null) {
			p = fc.getExternalContext().getInitParameter(key);
		}
		// TODO zmieniec na all
		log.log(Level.INFO, "getting property from FacesContext for key: "+ key + " -> " + p);
		return p;
	}
	
	public static String getFacesProperty(String key, ServletContext sc) {
		String p = null;
		if (sc != null) {
			p = sc.getInitParameter(key);
		}
		// TODO zmieniec na all
		log.log(Level.INFO, "getting property from ServletContext for key: "+ key + " -> " + p);
		return p;
	}
}
